﻿#pragma once
#pragma once
/**
* @brief tcp_client
* 方便与对端建立连接、数据通信
*/
#include <uv.h>
#include <string>
#include <functional>
#include "loop_controller.h"

class tcp_connect;
typedef std::function<void(tcp_connect* tcpconn, char* buf, int bsize)> conn_read_call;
typedef std::function<void(tcp_connect* tcpconn)> conn_close_call;
typedef std::function<void(tcp_connect* tcpconn)> conn_newconn_call;
class  DllExport tcp_connect
{
public:
	tcp_connect(uv_stream_t* stream);
	tcp_connect();
	~tcp_connect();
	/**
	* @brief 网络数据回调
	* @param 形参 参数说明
	* @param 形参 参数说明
	* @return 无
	* @note
	* @see
	*/
	void on_bytes_call(conn_read_call rdcb){ _conn_rd_cb = rdcb; }
	/**
	 * @brief 设置接收缓冲区大小
	 * @param int bufsize	 
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	void set_revbufsize(int bufsize){ _bufsize = bufsize; }
	/**
	 * @brief 设置关闭连接回调函数
	 * @param conn_close_call closecb	 
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	void on_close(conn_close_call closecb){ _close_cb = closecb; }
	/**
	* @brief  往对端写数据
	* @param buf	缓冲区地址
	* @param bsize	缓冲区大小
	* @return 无
	* @note 注意
	* @see
	*/
	void write_bytes(char* buf, size_t bsize);
	/**
	 * @brief 关闭连接 	 
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	void close();
	/**
	* @brief 处理读字节数据
	* @param buf 缓冲区
	* @param nread	读取字节数
	* @return 无
	* @note 注意
	* @see
	*/
	void process_read_bytes(const uv_buf_t* buf, ssize_t nread);
	/**
	 * @brief 处理buf分配 
	 * @param uv_buf_t* buf	 
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	void process_buf_alloc(uv_buf_t* buf);
	/**
	 * @brief 处理写返回 
	 * @param uv_write_t* req
	 * @param int status
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	void process_write_return(uv_write_t* req, int status);
	/**
	 * @brief 处理连接关闭 （当收到对端连接断开时处理）
	 * @param uv_handle_t* handle	 
	 * @return 无
	 * @note 注意
	 * @see  
	 */
	virtual void process_on_close(uv_handle_t* handle);
protected:
	uv_stream_t* _stream = nullptr;
	conn_close_call _close_cb;
	conn_read_call _conn_rd_cb;	
	int _bufsize = 1024 * 1024;
	char* _bufptr = nullptr;
	bool _bfreestream;
};

void internal_on_write(uv_write_t* req, int status);
void internal_on_close(uv_handle_t* handle);
void internal_on_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
void internal_on_alloc_buf(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);